extern crate pulse_simple as pa;

use std::{thread, mem};

use std::sync::{Arc, Mutex};

pub type AudioSample = [f32; 1];

pub struct PulseThread {
    audio_buffer_size: usize,
    record: pa::Record<AudioSample>,
    data: Arc<Mutex<Vec<AudioSample>>>
}

pub struct PulseHandle {
    data: Arc<Mutex<Vec<AudioSample>>>
}

impl PulseThread {
    pub fn run(self) {
        let mut buffer: Vec<AudioSample> = create_audio_buffer(self.audio_buffer_size);
        loop {
            self.record.read(&mut buffer[..]);
            let mut guard = self.data.lock().unwrap();
            mem::swap(&mut *guard, &mut buffer);
        }
    }
}

impl PulseHandle {
    pub fn get_data(&self) -> Vec<AudioSample> {
        let guard = self.data.lock().unwrap();
        (*guard).clone()
    }
}

fn create_audio_buffer(audio_buffer_size: usize) -> Vec<AudioSample> {
    vec![[0.]; audio_buffer_size]
}

pub fn start_thread(sample_rate: u32, audio_buffer_size: usize) -> PulseHandle {
    let buffer = create_audio_buffer(audio_buffer_size);
    let data = Arc::new(Mutex::new(buffer));
    let handle_data = data.clone();
    thread::spawn(move || {
        let rec = pa::Record::new("rust-audio-visualizer", "", sample_rate);
        let t = PulseThread {data: data, record: rec, audio_buffer_size: audio_buffer_size};
        t.run();
    });
    PulseHandle {data: handle_data}
}
